#include "xn297l.h"
#include "config.h"

static void xn297lInit(void);
static void xn297lSetChannel(void);
static void xn297lTxData(void);

static void xn297lCheck(void);
static void connect(void);

static u8 sendBuf[32];
static u8 readBuf[32];
xn297l_t xn297l = 
{
    .address ={'m','o','r','e','n'},//{0xc0,0xcc,0xcc,0xcc,0xcc},// 
    .channel = 1,
    .payload = 32,
    .transType = TRANS_ENHANCE_MODE,
    .dataRate = DR_1M,
    .rfPower = RF13dBm,
    .mode = TX,
    .pSendData = sendBuf,
    .pReadData = readBuf,
    .check = xn297lCheck,
    .init = xn297lInit,
    .send = xn297lTxData,
    .read = xn297lRxData,
    .switchChannel = xn297lSetChannel,
    .connect = connect,
};
xn297l_t *pXn297l = &xn297l;


static void xn297lWriteReg(uint8_t reg, uint8_t wdata)
{
    uint8_t sendData[2] = {reg, wdata};
    spi_master_transmit_receive(sendData, NULL, 2);
}

static uint8_t xn297lReadReg(uint8_t reg)
{
    uint8_t sendData[2] = {reg};
    spi_master_transmit_receive(sendData, sendData, 2);
    return sendData[1];
}

void xn297lWriteBuf( uint8_t reg, uint8_t *pBuf, uint8_t length)
{
    uint8_t sendData[100] = {reg};
    memcpy(sendData+1, pBuf, length);
    spi_master_transmit_receive(sendData, NULL, length+1);
}

static void xn297lReadBuf(uint8_t reg, uint8_t *pBuf, uint8_t length)
{
    uint8_t sendData[100] = {reg};
    spi_master_transmit_receive(sendData, sendData, length+1);
    memcpy(pBuf, sendData+1, length);
}

/*
 *Input: void
 *Description: 改变收发通道（0~78）
 *Return: void
 */
void xn297lSetChannel()
{    
    xn297lWriteReg(W_REGISTER + RF_CH, pXn297l->channel);
}


void xn297lTxData()
{
	uint8_t Status_Temp = 0;
	xn297lWriteBuf(W_TX_PAYLOAD, uartBuf, pXn297l->payload);   
    
    // xn297lWriteBuf(W_ACK_PAYLOAD, uartBuf, pXn297l->payload);
    while(READ_IRQ == RESET)
	{
		Status_Temp = xn297lReadReg(STATUS);
        if (Status_Temp & 0x30)
        {
            break;
        }
	}

     if (Status_Temp == 0)
     {
         Status_Temp = xn297lReadReg(STATUS);
     }
	
     if(Status_Temp == 96)
     {
     	xn297lReadBuf(R_RX_PAYLOAD, pXn297l->pReadData, pXn297l->payload );	
     	xn297lWriteReg(FLUSH_RX,0); 
        sendData(pXn297l->pReadData, pXn297l->payload);
        //sendData(pXn297l->pReadData, pXn297l->payload);
     }
    xn297lWriteReg(FLUSH_TX,0); 	
    xn297lWriteReg(W_REGISTER + STATUS, 0x70);                                 		//清除Status
    pWrite = uartBuf; 
}	


void xn297lRxData()
{
    static u8 lossCount = 0;
    static u8 ledOnFlag = 0;
#if 0
    static u16 count = 0;

    u8 t_length = pWrite - pRead;
    if(t_length)
    {
        while(pWrite != pRead)
        {
            pRead++;
            if(pRead - uartBuf == BUF_LENGTH)
            {
                pRead = uartBuf;
            }
        }
        count = 1;
    }
    //给一定的延时来判断输入的长度，不能太短
    //太短可能得到的值小了
    //太长得到的值又打了
    //目前测试100HZ下正常
    if(count)
    {
        count++;
        if(count > 5)
        {
            count = 0;
            pRead = pWrite = uartBuf;
        }
    }
#endif
    if(READ_IRQ == RESET)
    {
        //pWrite = pRead;
        xn297lWriteBuf(W_ACK_PAYLOAD, uartBuf, pXn297l->payload);
        
        xn297lReadBuf(R_RX_PAYLOAD, pXn297l->pReadData, pXn297l->payload);
		
        //xn297lWriteBuf(W_ACK_PAYLOAD, pXn297l->pSendData, pXn297l->payload); 
        //xn297lWriteReg(FLUSH_RX, 0);
        sendData(pXn297l->pReadData, pXn297l->payload);

        pWrite = uartBuf; 
        //delay();
        //__asm("NOP\n""NOP\n""NOP\n""NOP\n""NOP\n""NOP\n""NOP\n""NOP\n""NOP\n");

        //xn297lWriteReg(FLUSH_TX, 0);
        xn297lWriteReg(W_REGISTER + STATUS, 0x70);
#if 1        
        pXn297l->status = RECV_OK;
        lossCount = 0;
        
        if(ledOnFlag == 0)
        {
            LED_ON;
            ledOnFlag = 1;
        }
#endif        
    }
#if 1
    else
    {        
        //pXn297l->status = RECV_FAIL;
        if(lossCount < 250)
        {
            lossCount++;
        }
        else if(ledOnFlag)
        {
            LED_OFF;
            ledOnFlag = 0;
        }
    }
#endif
}

void xn297lCheck(void)
{ 
    xn297lWriteReg(W_REGISTER+TX_ADDR, 0xad);//往地址写入0xaa
    //从地址读出看还是不是写入的值
	pXn297l->status = ((0xad == xn297lReadReg(TX_ADDR)) ? SELF_OK : SELF_FAIL);
}

void connect(void)
{
#if !(TEST_CH)    
    static u16 count = 0;
    //第一个循环，先判断是不是连上的遥控器开启
    while(count < 1000)
    {
        pXn297l->read();
        if(pXn297l->status == RECV_OK)
        {
            return;//是则结束，不做操作
        }
        count++;
    }
    count = 0;
    //第二个循环，切换到默认地址
    //判断是否能和遥控连上
    //连上则记录新的地址（遥控在对频模式）
    memcpy(pXn297l->address, "moren", 5);
    pXn297l->channel = 1;//默认对频值
    pXn297l->init();
    while(count < 1000)
    {
        if(READ_IRQ == RESET)//接收引脚中断
        {
            xn297lWriteBuf(W_ACK_PAYLOAD, pXn297l->pSendData, pXn297l->payload); 
            xn297lReadBuf(R_RX_PAYLOAD, pXn297l->pReadData, pXn297l->payload);
            //先保存新地址数据
            memcpy(pFlashData->address, pXn297l->pReadData, 5);
            saveData();
            
            //清buf(可以不用，因为后面要初始化)
            //xn297lWriteReg(FLUSH_RX, 0);
            //xn297lWriteReg(FLUSH_TX, 0);
            //xn297lWriteReg(W_REGISTER + STATUS, 0x70);
            break;
        }
        count++;
    }

    //用flash的值初始化
    memcpy(pXn297l->address, pFlashData->address, 5);
    pXn297l->channel = (pXn297l->address[0] % 60);//默认对频值
    pXn297l->init();

#else
	//测试射频 （单载波）
    uint8_t powerTest[12] = {RF_30dBm, RF_18dBm, RF_10dBm, RF_6dBm, RF_3dBm, RF0dBm, RF2dBm, RF4dBm, RF5dBm, RF7dBm, RF8dBm, RF10dBm};
	uint8_t power = powerTest[5] | DATA_RATE;
	xn297lCarrier(0, power);
#endif
}

/*
 *Input:void 
 *Description: 初始化XN297，增强模式，配置不要乱改
 *Return: void
 */
void xn297lInit(void)
{
    uint8_t  BB_cal_data[]    = {0x2a,0xec,0x6f,0x9c,0x46};
    uint8_t  RF_cal_data[]    = {0xf6,0x37,0x5d};
    uint8_t  RF_cal2_data[]   = {0xd5,0x21,0xef,0x2c,0x5a,0x40};
    uint8_t  Dem_cal_data[]   = {0x01};   
    uint8_t  Dem_cal2_data[]  = {0x0b,0xdf,0x02};   
	     	
    xn297lWriteReg(RST_FSPI, 0x5A);							//Software Reset    			
    xn297lWriteReg(RST_FSPI, 0XA5);
    xn297lWriteReg(FLUSH_RX, 0);							// CLEAR  RXFIFO	
    xn297lWriteReg(FLUSH_TX, 0);							// CLEAR TXFIFO		
    xn297lWriteReg(W_REGISTER + STATUS, 0x70);				// CLEAR  STATUS	
    xn297lWriteReg(W_REGISTER + EN_RXADDR, 0x01);			// Enable Pipe0
    xn297lWriteReg(W_REGISTER + SETUP_AW,  0x03);			// address witdth is 5 bytes
    xn297lWriteReg(W_REGISTER + RF_CH,     pXn297l->channel);// 2401M HZ     
    xn297lWriteReg(W_REGISTER + RX_PW_P0,  pXn297l->payload);// bytes
    xn297lWriteBuf(W_REGISTER + TX_ADDR, pXn297l->address, 5);// Writes TX_Address to PN006		
    xn297lWriteBuf(W_REGISTER + RX_ADDR_P0, pXn297l->address, 5);// RX_Addr0 same as TX_Adr for Auto.Ack   

    xn297lWriteBuf(W_REGISTER + BB_CAL,    BB_cal_data,  sizeof(BB_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL2,   RF_cal2_data, sizeof(RF_cal2_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL,   Dem_cal_data, sizeof(Dem_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL,    RF_cal_data,  sizeof(RF_cal_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL2,  Dem_cal2_data,sizeof(Dem_cal2_data));   
      
    xn297lWriteReg(W_REGISTER + DYNPD, 0x00);					   
    xn297lWriteReg(W_REGISTER + RF_SETUP,  (pXn297l->dataRate | pXn297l->rfPower));						//DBM  	
	
    
    if(pXn297l->transType == TRANS_ENHANCE_MODE)      	
    {
        xn297lWriteReg(ACTIVATE, 0x73);	//如果使用W_ACK则需要这句
        xn297lWriteReg(W_REGISTER + SETUP_RETR,0x01);//  3 retrans... 	
        xn297lWriteReg(W_REGISTER + EN_AA,     0x01);// Enable Auto.Ack:Pipe0  
        xn297lWriteReg(W_REGISTER + FEATURE, 0x02);
    }
    else if(pXn297l->transType == TRANS_BURST_MODE)
    {
        xn297lWriteReg(W_REGISTER + SETUP_RETR,0x00);// Disable retrans... 	
        xn297lWriteReg(W_REGISTER + EN_AA,     0x00);// Disable AutoAck 
        xn297lWriteReg(W_REGISTER + FEATURE, 0x00);
    }

    //xn297l通信模式设置
    if(pXn297l->mode == TX)
    {
        xn297lWriteReg(W_REGISTER + CONFIG,  0XCE);     // 将RF设置成TX模式
    }
    else
    {
        xn297lWriteReg(W_REGISTER + CONFIG,  0XBF );    // 将RF设置成RX模式   
    }
    delay();
}

/******************************************************************************/
//            		进入载波模式
/******************************************************************************/
void xn297lCarrier( uint8_t ucChannel_Set, uint8_t power)
{
    uint8_t BB_cal_data[]    = {0x0A,0x6D,0x67,0x9C,0x46}; 
    uint8_t RF_cal_data[]    = {0xF6,0x37,0x5D};
    uint8_t RF_cal2_data[]   = {0x45,0x21,0xEF,0xAC,0x5A,0x50};
    uint8_t Dem_cal_data[]   = {0xE1}; 								
    uint8_t Dem_cal2_data[]  = {0x0B,0xDF,0x02};      

    xn297lWriteReg(RST_FSPI, 0x5A);								//Software Reset    			
    xn297lWriteReg(RST_FSPI, 0XA5);
    delay(200);
    xn297lWriteReg(W_REGISTER + RF_CH, ucChannel_Set);						//单载波频点	   
    xn297lWriteReg(W_REGISTER + RF_SETUP, power);      						//dbm
    xn297lWriteBuf(W_REGISTER + BB_CAL,    BB_cal_data,  sizeof(BB_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL2,   RF_cal2_data, sizeof(RF_cal2_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL,   Dem_cal_data, sizeof(Dem_cal_data));
    xn297lWriteBuf(W_REGISTER + RF_CAL,    RF_cal_data,  sizeof(RF_cal_data));
    xn297lWriteBuf(W_REGISTER + DEM_CAL2,  Dem_cal2_data,sizeof(Dem_cal2_data));
}

/***************************************end of file ************************************/


